import axios from 'axios'
import qs from 'qs'
import { isFunction } from '@/utils/is.js'

// 声明一个Map，用于存储每个请求的标识和取消函数
let pendingMap = new Map()

export const getPendingUrl = (config) => {
  return [config.method, config.url, qs.stringify(config.data), qs.stringify(config.params)].join('&')
}

export class AxiosCanceler {
  /**
  * @description 添加请求
  * @param {Object} config
  */
  addPending(config) {
    // 每次添加请求之前先清除之前的请求
    this.removePending(config)
    const url = getPendingUrl(config)
    // 获取axios取消的静态方法--是一个构造函数
    const CancelToken = axios.CancelToken
    config.cancelToken = config.cancelToken || new CancelToken(cancel => !pendingMap.has(url) && pendingMap.set(url, cancel))
  }

  /**
  * @description 移除请求
  * @param {Object} config
  */
  removePending(config) {
    const url = getPendingUrl(config)
    // pendingMap中存在当前请求标识，需要取消当前请求且移除
    if (pendingMap.has(url)) {
      const cancel = pendingMap.get(url)
      cancel && cancel(url)
      // 从pendingMap中将当前标识删掉
      pendingMap.delete(url)
    }
  }

  /**
  * @description 清空所有请求
  */
  clearPending() {
    pendingMap.forEach(cancel => {
      cancel && isFunction(cancel) && cancel()
    })
    pendingMap.clear()
  }

  /**
  * @description 重置pendingMap
  */
  resetPending() {
    pendingMap = new Map()
  }
}
